home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
raytrace
/
dbwrend
/
source
/
fil.c
< prev
next >
Wrap
Text File
|
1989-10-31
|
19KB
|
549 lines
/************************************************************************
* *
* Copyright (c) 1987, David B. Wecker *
* All Rights Reserved *
* *
* This file is part of DBW_Render *
* *
* DBW_Render is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY. No author or distributor accepts *
* responsibility to anyone for the consequences of using it or for *
* whether it serves any particular purpose or works at all, unless *
* he says so in writing. Refer to the DBW_Render General Public *
* License for full details. *
* *
* Everyone is granted permission to copy, modify and redistribute *
* DBW_Render, but only under the conditions described in the *
* DBW_Render General Public License. A copy of this license is *
* supposed to have been given to you along with DBW_Render so you *
* can know your rights and responsibilities. It should be in a file *
* named COPYING. Among other things, the copyright notice and this *
* notice must be preserved on all copies. *
************************************************************************
* *
* Authors: *
* DBW - David B. Wecker *
* jhl - John H. Lowery *
* *
* Versions: *
* V1.0 870125 DBW - First released version *
* V1.01 880916 jhl - IBM PC (VGA/MCGA) conversion *
* 890121 jhl - MAXROW & MAXCOL become variables, add *
* 'D' command for Display max <hor> <vert> *
* V1.02 891031 jhl - add MAXCOL and MAXROW as first two integers *
* in output file, so multiple formats can be *
* supported. *
* *
************************************************************************/
#define MODULE_FILEIO
#include "ray.h"
static long *fracopp;
static triangle *scr_t;
static extent *scr_e;
static sphere *scr_s;
static quad *scr_q;
static ring *scr_r;
static cylinder *scr_c;
static int whichf;
void dumpnode(n)
node *n;
{
while (n)
{
switch (n->kind)
{
case EXTENT :
printf("extent\n");
vecdump(eptr(n)->center,"center");
printf("radius = %f\n",eptr(n)->radius);
dumpnode(((extent *) n)->sub);
break;
case SPHERE :
printf("sphere\n");
break;
case TRIANGLE :
printf("triangle\n");
break;
case QUAD :
printf("quad\n");
break;
case RING :
printf("ring\n");
break;
default :
printf("UNKNOWN KIND %d\n",n->kind);
break;
}
n = n->next;
}
printf("end\n");
}
void copyattr( oa, na )
attributes *oa, *na;
{
na->ref = oa->ref;
na->idx = oa->idx;
na->fuz = oa->fuz;
na->tex = oa->tex;
veccopy( oa->tra, na->tra );
veccopy( oa->amb, na->amb );
veccopy( oa->dif, na->dif );
}
void read_vec(v)
vector v;
{
fscanf(df,"%f %f %f",&v[0],&v[1],&v[2]);
}
void read_attr(attr)
attributes *attr;
{
fscanf(df,"%d %f %f %f",&attr->tex,&attr->fuz,&attr->ref,&attr->idx);
read_vec(attr->tra);
read_vec(attr->amb);
read_vec(attr->dif);
if (attr->tra[0] > 0.0 || attr->tra[1] > 0.0 || attr->tra[2] > 0.0)
allopaque = 0;
attr->fuz /= 10.0; /* Assume more reasonable scale */
}
void dofractal(level,a,b,c,attr)
int level;
vector a,b,c;
attributes *attr;
{
float aclen,bclen,ablen;
vector ab,ac,bc,abbump,acbump,bcbump,v1;
long *savedopp;
if (level == 1)
{
CHECK_ALLOC(scr_t,triangle);
*fracopp = (long)scr_t;
tptr(*fracopp)->next = NULL;
tptr(*fracopp)->kind = TRIANGLE;
copyattr(attr,&tptr(*fracopp)->attr);
veccopy(a,tptr(*fracopp)->position);
vecsub(c,a,ac);
veccopy(ac,tptr(*fracopp)->ve);
vecsub(b,a,ab);
veccopy(ab,tptr(*fracopp)->vp);
fracopp = (long *) &tptr(*fracopp)->next;
}
else
{
level--;
/* compute four subfaces */
/* length of edges */
vecsub(a,c,v1);
aclen = norm(v1);
vecsub(a,b,v1);
ablen = norm(v1);
vecsub(b,c,v1);
bclen = norm(v1);
/* edge midpoints */
vecsum(a,c,ac);
vecscale(0.5,ac,ac);
vecsum(a,b,ab);
vecscale(0.5,ab,ab);
vecsum(b,c,bc);
vecscale(0.5,bc,bc);
/* midpoint perturbations */
noise3(ac,acbump);
if (ac[1] == 0.0)
acbump[1] = 0.0;
noise3(ab,abbump);
if (ab[1] == 0.0)
abbump[1] = 0.0;
noise3(bc,bcbump);
if (bc[1] == 0.0)
bcbump[1] = 0.0;
acbump[0] *= fractal[whichf].xscale;
acbump[1] *= fractal[whichf].yscale;
acbump[2] *= fractal[whichf].zscale;
bcbump[0] *= fractal[whichf].xscale;
bcbump[1] *= fractal[whichf].yscale;
bcbump[2] *= fractal[whichf].zscale;
abbump[0] *= fractal[whichf].xscale;
abbump[1] *= fractal[whichf].yscale;
abbump[2] *= fractal[whichf].zscale;
/* scale the perturbations proportional to side length */
vecscale(aclen,acbump,acbump);
vecscale(ablen,abbump,abbump);
vecscale(bclen,bcbump,bcbump);
/* new perturbed midpoints */
vecsum(abbump,ab,ab);
vecsum(acbump,ac,ac);
vecsum(bcbump,bc,bc);
CHECK_ALLOC(scr_e,extent);
*fracopp = (long)scr_e;
eptr(*fracopp)->next = NULL;
eptr(*fracopp)->kind = EXTENT;
eptr(*fracopp)->sub = NULL;
savedopp = &*fracopp;
fracopp = (long *) &eptr(*fracopp)->sub;
dofractal(level,a, ab,ac,attr);
dofractal(level,ac,bc,c, attr);
dofractal(level,ab,b, bc,attr);
dofractal(level,ac,ab,bc,attr);
fracopp = (long *) &eptr(*savedopp)->next;
}
}
void readimagefile(opp)
long *opp;
{
triangle temp;
vector a,b,c;
while (EOF != fscanf(df,"%1s",str))
switch(str[0])
{
case 'D' :
fscanf(df,"%d %d",&MAXCOL,&MAXROW);
if (MAXCOL > MAXX)
MAXCOL = MAXX;
if (MAXROW > MAXY)
MAXROW = MAXY;
break;
case 'R' :
fscanf(df,"%f",&maxhours);
break;
case 'N' :
fscanf(df,"%f",&idxref);
break;
case 'Z' :
fscanf(df,"%d",&histogram);
break;
case 'a' :
fscanf(df,"%f",&ambscale);
break;
case 'A' :
fscanf(df,"%d %f",&antialias,&variance);
break;
case 'F' :
fscanf(df,"%f %f",&aperture,&focus);
break;
case 'M' :
fscanf(df,"%d %d %d",&ambientlight,&amblitnum,&amblitdenom);
break;
case '&' :
fscanf(df,"%d %d",&startrow,&endrow);
break;
case '*' :
fgets(fname,255,df); /* get, and display */
printf("%s",fname);
break;
case '!' :
fgets(fname,255,df); /* get, and throw away */
break;
case 'b' :
read_vec(backgroundval);
break;
case 'w' :
read_vec(wave[numwaves].center);
fscanf(df,"%f",&wave[numwaves].wavelength);
fscanf(df,"%f",&wave[numwaves].amplitude);
fscanf(df,"%f",&wave[numwaves].drag);
fscanf(df,"%f",&wave[numwaves].propagate);
wave[numwaves].wavelength /= 2.0; /* need half-wave */
wave[numwaves].propagate /= 2.0; /* need half-wave */
numwaves++;
break;
case 'g' :
read_vec(blend[numblends].color);
fscanf(df,"%f",&blend[numblends].start);
fscanf(df,"%f",&blend[numblends].scale);
numblends++;
break;
case 'n' :
fscanf(df,"%f",&snow[numsnows].start);
fscanf(df,"%f",&snow[numsnows].altscale);
fscanf(df,"%f",&snow[numsnows].altfactor);
fscanf(df,"%f",&snow[numsnows].threshhold);
numsnows++;
break;
case 'p' :
fscanf(df,"%f",&pebble[numpebbles].scale);
fscanf(df,"%f",&pebble[numpebbles].zoom);
numpebbles++;
break;
case 'k' :
read_vec(checker[numcheckers].color);
fscanf(df,"%f",&checker[numcheckers].x);
fscanf(df,"%f",&checker[numcheckers].y);
fscanf(df,"%f",&checker[numcheckers].z);
fscanf(df,"%f",&checker[numcheckers].bevel);
fscanf(df,"%f",&checker[numcheckers].angle);
fscanf(df,"%d", &checker[numcheckers].beveltype);
checker[numcheckers].bevel /= checker[numcheckers].x;
numcheckers++;
break;
case 'H' :
read_vec(haze[numhazes].color);
fscanf(df,"%f",&haze[numhazes].distscale);
numhazes++;
break;
case 'f' :
fscanf(df,"%d", &fractal[numfractals].level);
fscanf(df,"%f",&fractal[numfractals].xscale);
fscanf(df,"%f",&fractal[numfractals].yscale);
fscanf(df,"%f",&fractal[numfractals].zscale);
fscanf(df,"%d", &fractal[numfractals].texture);
numfractals++;
break;
case 'm' :
read_vec(marble[nummarble].veincolor);
fscanf(df,"%f",&marble[nummarble].xscale);
fscanf(df,"%f",&marble[nummarble].turbscale);
fscanf(df,"%d", &marble[nummarble].squeeze);
nummarble++;
break;
case 'd' :
read_vec(wood[numwoods].othercolor);
fscanf(df,"%f",&wood[numwoods].thickscale);
fscanf(df,"%f",&wood[numwoods].ringspacing);
fscanf(df,"%f",&wood[numwoods].turbscale);
fscanf(df,"%d", &wood[numwoods].squeeze);
numwoods++;
break;
case 'e' :
read_vec(eye);
read_vec(vrp);
read_vec(vu);
vecscale((float) MAXCOL / 256.0,vrp,vrp); /* uniform scale */
cross(vrp,vu,vr);
cross(vr,vrp,vu);
normalize(vu);
normalize(vr);
vecsum(vrp,eye,vrp);
break;
case 'l' :
light[numlits].kind = 0;
read_vec(light[numlits].intensity);
read_vec(light[numlits].direction);
normalize(light[numlits++].direction);
break;
case 'L' :
light[numlits].kind = 1;
read_vec(light[numlits].intensity);
read_vec(light[numlits].direction);
fscanf(df,"%f",&light[numlits].distscale);
fscanf(df,"%f",&light[numlits].radius);
light[numlits].distscale =
light[numlits].distscale * light[numlits].distscale;
numlits++;
break;
case '{' :
CHECK_ALLOC(scr_e,extent);
*opp = (long)scr_e;
eptr(*opp)->next = NULL;
eptr(*opp)->kind = EXTENT;
eptr(*opp)->sub = NULL;
readimagefile(&eptr(*opp)->sub);
opp = (long *) &eptr(*opp)->next;
break;
case '}' :
return;
break;
case 's' :
CHECK_ALLOC(scr_s,sphere);
*opp = (long)scr_s;
sptr(*opp)->next = NULL;
sptr(*opp)->kind = SPHERE;
read_attr(&sptr(*opp)->attr);
read_vec(sptr(*opp)->center);
fscanf(df,"%f",&sptr(*opp)->radius);
opp = (long *) &sptr(*opp)->next;
break;
case 't' :
CHECK_ALLOC(scr_t,triangle);
*opp = (long)scr_t;
tptr(*opp)->next = NULL;
tptr(*opp)->kind = TRIANGLE;
read_attr(&tptr(*opp)->attr);
read_vec(tptr(*opp)->position);
read_vec(tptr(*opp)->ve);
read_vec(tptr(*opp)->vp);
opp = (long *) &tptr(*opp)->next;
break;
case 'x' :
read_attr(&temp.attr);
read_vec(temp.position);
read_vec(c);
read_vec(b);
whichf = temp.attr.tex - 60;
temp.attr.tex = fractal[whichf].texture;
fracopp = &*opp;
dofractal(fractal[whichf].level,
temp.position,b,c,&temp.attr);
opp = &*fracopp;
break;
case 'q' :
CHECK_ALLOC(scr_q,quad);
*opp = (long)scr_q;
qptr(*opp)->next = NULL;
qptr(*opp)->kind = QUAD;
read_attr(&qptr(*opp)->attr);
read_vec(qptr(*opp)->position);
read_vec(qptr(*opp)->ve);
read_vec(qptr(*opp)->vp);
opp = (long *) &qptr(*opp)->next;
break;
case 'r' :
CHECK_ALLOC(scr_r ,ring);
*opp = (long)scr_r;
rptr(*opp)->next = NULL;
rptr(*opp)->kind = RING;
read_attr(&rptr(*opp)->attr);
read_vec(rptr(*opp)->position);
read_vec(rptr(*opp)->ve);
read_vec(rptr(*opp)->vp);
fscanf(df,"%f",&rptr(*opp)->minrad);
fscanf(df,"%f",&rptr(*opp)->maxrad);
rptr(*opp)->minrad =
rptr(*opp)->minrad * rptr(*opp)->minrad;
rptr(*opp)->maxrad =
rptr(*opp)->maxrad *rptr(*opp)->maxrad;
opp = (long *) &rptr(*opp)->next;
break;
case 'c' :
CHECK_ALLOC(scr_c ,cylinder);
*opp = (long)scr_c;
cptr(*opp)->next = NULL;
cptr(*opp)->kind = CYLINDER;
read_attr(&cptr(*opp)->attr);
read_vec(cptr(*opp)->bottom);
read_vec(cptr(*opp)->top);
fscanf(df,"%f",&cptr(*opp)->a);
fscanf(df,"%f",&cptr(*opp)->b);
fscanf(df,"%f",&cptr(*opp)->c);
opp = (long *) &cptr(*opp)->next;
break;
default :
sprintf(fname,"Bad command char '%c' encountered",str[0]);
ERROR(fname);
break;
}
}
void getinput(argc,argv)
int argc;
char **argv;
{
int i;
char *s, *strchr();
rextent re;
if (argc == 1)
{
printf("Scene description file? ");
scanf("%s",fname);
}
else
sprintf(fname,"%s",argv[1]);
/* if no filetype specified, default it */
if (strchr( fname, '.' ) == NULL)
{
strcat( fname, ".DAT" );
}
df = fopen(fname,"r");
if (df == NULL) /* v1.01 */
ERROR("Error opening input file."); /* v1.01 */
/* get name portion of file, append .$ST to it for statistics */
strcpy( outname, fname );
s = strchr( outname, '.'); /* guaranteed to be there */
if (s == NULL)
s = outname + strlen(outname); /* but just to be sure... */
*s = '\0';
strcat( outname, ".$ST" );
fpout = fopen(outname,"w");
if (fpout == NULL) /* v1.01 */
ERROR("Error opening statistics file."); /* v1.01 */
readimagefile(&root);
getextent(root,&re);
/* dumpnode(root); DEBUG output */
fclose(df);
}
void write_scanline()
{
int siz;
fwrite(&sline,1,sizeof(int),fp);
/*- 1/21/89 ---
fwrite(redline,1,sizeof(scanlinetype),fp);
fwrite(greenline,1,sizeof(scanlinetype),fp);
fwrite(blueline,1,sizeof(scanlinetype),fp);
-*/
siz = (MAXCOL/PPW)*sizeof(int); /* file line size */
fwrite(redline,1,siz,fp);
fwrite(greenline,1,siz,fp);
fwrite(blueline,1,siz,fp);
sline++;
}
void getoutput(argc,argv)
int argc;
char **argv;
{
if (argc == 1)
{
printf( "File name to save picture (.tmp)? " );
scanf( "%s", fname );
}
else
sprintf(fname,"%s.tmp",argv[1]);
#ifdef IBM_PC
fp = fopen(fname,"wb"); /* V1.01 - IBM level 2 i/o must be binary */
#else
fp = fopen(fname,"w");
#endif
if (fp == NULL)
{
ERROR( "Error creating output file." );
}
else
{
fwrite(&MAXCOL,1,sizeof( MAXCOL ),fp);
fwrite(&MAXROW,1,sizeof( MAXROW ),fp);
}
}